home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok70.lha / PL0 / txt / GeneralParser.mod next >
Text File  |  1993-08-15  |  5KB  |  233 lines

  1.  
  2. MODULE GeneralParser;
  3.  
  4. IMPORT
  5.   io,
  6.   asc: ASCII,
  7.   fs: FileSystem,
  8.   sys: SYSTEM;
  9.  
  10. TYPE
  11.   NodePtr = POINTER TO Node;
  12.   HeadPtr = POINTER TO Header;
  13.  
  14.   Node = RECORD
  15.     suc, alt: NodePtr;
  16.     terminal: BOOLEAN;
  17.     tsym: CHAR;
  18.     nsym: HeadPtr;
  19.   END;
  20.  
  21.   Header = RECORD
  22.     sym: CHAR;
  23.     entry: NodePtr;
  24.     suc: HeadPtr;
  25.   END;
  26.  
  27. CONST
  28.   empty = " ";
  29.  
  30. VAR
  31.   list, sentinel, h: HeadPtr;
  32.   q, r, s: NodePtr;
  33.   sym: CHAR;
  34.   noerr: BOOLEAN;
  35.   file: fs.File;
  36.  
  37.  
  38. PROCEDURE GetSym;
  39. BEGIN
  40.   REPEAT
  41.     IF fs.ReadChar(file,sym) THEN END;
  42.     io.Write(sym);
  43.   UNTIL (sym > " ") OR (sym = asc.esc);
  44. END GetSym;
  45.  
  46.  
  47. PROCEDURE find(s: CHAR; VAR h: HeadPtr);
  48. VAR
  49.   h1: HeadPtr;
  50. BEGIN
  51.   h1 := list;
  52.   sentinel.sym := s;
  53.   WHILE h1.sym # s DO
  54.     h1 := h1.suc; END;
  55.   IF h1 = sentinel THEN (* insert *)
  56.     NEW(sentinel);
  57.     h1.suc := sentinel;
  58.     h1.entry  := NIL;
  59.   END;
  60.   h := h1;
  61. END find;
  62.  
  63.  
  64. PROCEDURE error;
  65. BEGIN
  66.   noerr := FALSE;
  67.   io.WriteString("\n incorrect Syntax ");
  68. END error;
  69.  
  70.  
  71. PROCEDURE link(p,q: NodePtr);
  72. VAR
  73.   t: NodePtr;
  74. BEGIN (* insert q in places indecated by linked chain p *)
  75.   WHILE p#NIL DO
  76.     t := p; p := t.suc; t.suc := q;
  77.   END;
  78. END link;
  79.  
  80.  
  81. PROCEDURE expression(VAR p, q, r, s: NodePtr);
  82. VAR
  83.   q1, s1: NodePtr;
  84.  
  85.   PROCEDURE term(VAR p, q, r, s: NodePtr);
  86.   VAR
  87.     p1, q1, r1, s1: NodePtr;
  88.  
  89.     PROCEDURE factor(VAR p, q, r, s: NodePtr);
  90.     VAR
  91.       a: NodePtr;
  92.       h: HeadPtr;
  93.     BEGIN
  94.       IF ("A" <= CAP(sym)) & (CAP(sym) <= "Z") THEN
  95.         NEW(a);
  96.         find(sym,h);
  97.         a.terminal := FALSE;
  98.         a.nsym := h;
  99.         a.alt := NIL;
  100.         a.suc := NIL;
  101.         p := a; q := a; r := a; s := a;
  102.         GetSym;
  103.       ELSIF sym = '"' THEN (* terminal symbol *)
  104.         GetSym;
  105.         NEW(a);
  106.         a.terminal := TRUE;
  107.         a.tsym := sym;
  108.         a.alt := NIL;
  109.         a.suc := NIL;
  110.         p := a; q := a; r := a; s := a;
  111.         GetSym;
  112.         IF sym = '"' THEN GetSym ELSE error; END;
  113.       ELSIF sym = "(" THEN
  114.         GetSym;
  115.         expression(p,q,r,s);
  116.         IF sym = ")" THEN GetSym ELSE error; END;
  117.       ELSIF sym = "[" THEN
  118.         GetSym;
  119.         expression(p,q,r,s);
  120.         NEW(a);
  121.         a.terminal := TRUE;
  122.         a.tsym := empty;
  123.         a.alt := NIL;
  124.         a.suc := NIL;
  125.         q.alt := a; s.suc := a; q := a; s := a;
  126.         IF sym = "]" THEN GetSym ELSE error; END;
  127.       ELSIF sym = "{" THEN
  128.         GetSym;
  129.         expression(p,q,r,s);
  130.         link(r,p);
  131.         NEW(a);
  132.         a.terminal := TRUE;
  133.         a.tsym := empty;
  134.         a.alt := NIL;
  135.         a.suc := NIL;
  136.         q.alt := a; r := a; q := a; s := a;
  137.         IF sym = "}" THEN GetSym ELSE error; END;
  138.       ELSE error;
  139.       END;
  140.     END factor;
  141.  
  142.   BEGIN (* term *)
  143.     factor (p,q,r,s);
  144.     WHILE ("A" <= CAP(sym)) & (CAP(sym) <= "Z") OR
  145.           (sym = '"') OR (sym = "(") OR (sym = "[") OR
  146.           (sym = "{") DO
  147.       factor(p1,q1,r1,s1);
  148.     END;
  149.   END term;
  150.  
  151. BEGIN (* expression *)
  152.   term (p,q,r,s);
  153.   WHILE sym = "|" DO
  154.     GetSym;
  155.     term(q.alt,q1,s.suc,s1);
  156.     q := q1; s := s1;
  157.   END;
  158. END expression;
  159.  
  160.  
  161. PROCEDURE parse(goal: HeadPtr; VAR match: BOOLEAN);
  162. VAR
  163.   s: NodePtr;
  164. BEGIN
  165.   s := goal.entry;
  166.   REPEAT
  167.     IF s.terminal THEN
  168.       IF s.tsym = sym THEN
  169.         match := TRUE;
  170.         GetSym;
  171.       ELSE
  172.         match := s.tsym = empty;
  173.       END;
  174.     ELSE
  175.       parse(s.nsym,match);
  176.     END;
  177.     IF match THEN s := s.suc; ELSE s := s.alt; END;
  178.   UNTIL s = NIL;
  179. END parse;
  180.  
  181.  
  182. BEGIN (* main *)
  183.   IF fs.Open(file,"EBNF",FALSE) THEN noerr := TRUE;
  184.     NEW(sentinel); list := sentinel;
  185.  
  186.     (* read products and buils data structure *)
  187.     LOOP
  188.       GetSym;
  189.       IF sym = "$" THEN EXIT; END;
  190.       find (sym,h);
  191.       GetSym;
  192.       IF sym = "=" THEN GetSym ELSE error END;
  193.       expression(h.entry,q,r,s);
  194.       link(r,NIL);
  195.       IF sym # "." THEN error END;
  196.     END;
  197.  
  198.     IF noerr THEN
  199.       h := list;
  200.       (* check wether all symbols are defined *)
  201.       WHILE h # sentinel DO
  202.         IF h.entry = NIL THEN
  203.           io.WriteString(" undefined Symbol ");
  204.           io.Write(h.sym); io.WriteLn;
  205.           noerr := FALSE;
  206.         END;
  207.         h := h.suc;
  208.       END;
  209.     END;
  210.  
  211.     IF noerr THEN (* read goal symbol *)
  212.       GetSym; find (sym,h); io.WriteLn;
  213.       IF fs.Close(file) THEN END;
  214.       (* read and parse sentences *)
  215.       LOOP
  216.         io.Write(">");
  217.         GetSym;
  218.         IF sym = asc.esc THEN EXIT END;
  219.         parse(h,noerr);
  220.         IF noerr & (sym = asc.esc) THEN
  221.           io.WriteString("  correct\n");
  222.         ELSE
  223.           io.WriteString("  incorrect\n");
  224.         END;
  225.       END;
  226.     ELSE
  227.       IF fs.Close(file) THEN END;
  228.     END;
  229.     io.WriteLn;
  230.   END;
  231. END GeneralParser.
  232.  
  233.